package eval

import (
	"showen/lex"
	"showen/obj"
	"showen/parse"
	"testing"
)

func TestNumberToStringIntegration(t *testing.T) {
	tests := []struct {
		name     string
		input    string
		expected string
	}{
		{
			"integer to string",
			`(number->string 42)`,
			`"42"`,
		},
		{
			"negative integer to string",
			`(number->string -123)`,
			`"-123"`,
		},
		{
			"real to string",
			`(number->string 3.14)`,
			`"3.14"`,
		},
		{
			"rational to string",
			`(number->string 3/4)`,
			`"3/4"`,
		},
		{
			"integer to octal string",
			`(number->string 42 8)`,
			`"52"`,
		},
		{
			"integer to hexadecimal string",
			`(number->string 42 16)`,
			`"2a"`,
		},
		{
			"integer to binary string",
			`(number->string 42 2)`,
			`"101010"`,
		},
	}

	env := obj.NewEnvironment()
	RegisterBuiltinProcedures(env)

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			lexer := lex.NewLexer(tt.input)
			tokens := lexer.ReadTokens()
			parser := parse.NewParser(tokens)
			expr, err := parser.ParseExpression()
			if err != nil {
				t.Fatalf("ParseExpression() error = %v", err)
			}

			result, err := EvalExpression(expr, env)
			if err != nil {
				t.Fatalf("EvalExpression() error = %v", err)
			}

			if result.Inspect() != tt.expected {
				t.Errorf("EvalExpression() = %v, want %v", result.Inspect(), tt.expected)
			}
		})
	}
}
